# -- coding: utf-8 --
"""
# MIAHX© 点云数据帧消息的 FastDDS 发布器

**模块：MIAHX© / 框架基础服务层（FFST） / 交互框架信息表示模型（IFIRM）**

Version: 0.4.10,
Last updated: October 20, 2024

## Contributor(s)
* YAO Naiming <[naiming@iscas.ac.cn](mailto:naiming@iscas.ac.cn)>

## Change log
### v0.4.10
- .20: [优化] Reader 构造方法传入 topic_name
- .13: [更新] 适配新的消息定义，重命名，重新实现 write
- .2: [新增] 迁移重构实现

---
Copyright © 2024-2025 MIAHX Contributors, ISCAS, and ASIC. All Rights Reserved.
Licensed under Apache-2.0.
"""

import os

import miahx_fastdds as dds
import numpy as np
from loguru import logger

from .participant import Participant
from .reader import Reader, ReaderListener
from .writer import Writer

_log = logger.bind(module_name=os.path.basename(__file__))


class PointCloudStreamReader(Reader):
    """
    点云样本数据流读取器
    """

    def __init__(self, participant: Participant, topic_name: str, on_data_listeners=None):
        """
        创建点云样本数据流读取器

        :param participant: FastDDS 参与者
        :param topic_name: FastDDS 主题名称
        :param on_data_listeners: 数据监听回调列表
        """
        topic_data_type = dds.PointCloudDataFramePubSubType()
        super().__init__(participant, topic_name, topic_data_type,
                         listener=ReaderListener(topic_name, topic_data_type, on_data_listeners))


class PointCloudStreamWriter(Writer):
    """
    点云样本数据流读写入器
    """

    def __init__(self, participant: Participant, topic_name: str,
                 stag: int = None, srate: int = None, schns: list[str] = None):
        """
        创建点云样本数据流写入器

        :param participant: FastDDS 参与者
        :param topic_name: FastDDS 主题名称
        :param stag: 传感器标签，由 STag 类型生成
        :param srate: 传感器采样率，单位 Hz
        :param schns: 传感器数据通道定义
        """
        super().__init__(participant, topic_name, dds.PointCloudDataFramePubSubType(),
                         stag=stag, srate=srate, schns=schns)

    def write(self, chunk: list[tuple[int, float, np.ndarray, np.ndarray]],
              iid: int = None, uts: float = None):
        """
        写入点云数据样本

        :param chunk: 样本数据描述，列表，每个元素为一个元组，表示：(样本的全局校准单调递增序号，样本的全局校准 POSIX 时间戳，样本数据)
        :param iid: 全局校准的单调递增序号
        :param uts: 全局校准的 POSIX 时间戳
        """
        # header
        frame = dds.PointCloudDataFrame()
        frame.header(self._create_frame_header(uts, iid))
        #
        samples = []
        for item in chunk:
            iid, uts, points, colours = item
            sample = dds.PointCloudSample()
            if points is not None:
                assert isinstance(points, np.ndarray) and points.dtype == np.float32
                sample.points(points.flatten().tolist())
            if colours is not None:
                assert colours.dtype == np.uint8
                sample.colours(colours.flatten().tolist())
            samples.append(sample)
        frame.samples(samples)
        #
        self._writer.write(frame)
